home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / Shells / Matrix11.lha / src / Matrix.C
Encoding:
C/C++ Source or Header  |  1994-01-07  |  13.9 KB  |  596 lines

  1. ;/*
  2. DCC Matrix.C -o Matrix
  3. ;Copy Matrix AXsh:bin/matrix
  4. Quit
  5. */
  6.  
  7. /*
  8.  
  9. /***********************************************************************
  10.  *                        MATRIX MENU SYSTEM V1.1                      *
  11.  *                               _                                     *
  12.  *                         by Guru Gnosis Sahib                        *
  13.  ***********************************************************************
  14.  
  15. v1.0 - 29-Dec-93 - First functional version
  16. v1.1 - 07-Jan-93 - Added carrier-lost logouts; added CTRL-C processing;
  17.                    disabled user from entering MSG_* in menu;
  18.                    changed all gets() to fgets(stdin); fixed bug allowing
  19.                    user to give any menu file as argument; superuser is
  20.                    now {assistant, superuser, wizard, assistant, system}
  21. */
  22.  
  23. #include <ctype.h>
  24. #include <signal.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <time.h>
  28. #include <libraries/dos.h>
  29. #include <dos/dostags.h>
  30. #include <dos/var.h>
  31. #include <exec/types.h>
  32. #include <exec/memory.h>
  33. #include <exec/ports.h>
  34. #include <intuition/intuition.h>
  35.  
  36. #define VERSION         "1.1"
  37. /* #define VERSION_2        "Yup" */
  38.  
  39. #define NORMAL            0
  40. #define SUPERUSER         1
  41.  
  42. #define MAX_ITEM         50            /* Maximum menu items */
  43.  
  44. struct Item
  45. {
  46.     char Cmd[80];
  47.     char Key[10];
  48.     BOOL CheckPath;
  49.     BOOL RawMode;
  50.     BOOL AskFile;
  51.     char String[80];
  52.     BOOL Pause;
  53. };
  54.  
  55. struct MatrixMsg
  56. {
  57.     struct Message mm_Msg;
  58.     char mm_Text[80];
  59. };
  60.  
  61. struct Item il[MAX_ITEM];
  62. struct MsgPort *matrix_mp;
  63. struct MatrixMsg *matrix_msg;
  64.  
  65. FILE *input, *output, *output2;
  66. int icount;
  67.  
  68. void breakexit(void);
  69.  
  70. main(argc,argv)
  71. int argc;
  72. char *argv[];
  73. {
  74.     BPTR fp, lock;
  75.     BOOL exit_chosen = FALSE, timeout = FALSE, skip = FALSE, expert = FALSE,
  76.         cmddone = FALSE, newmenu = FALSE;
  77.  
  78.     char validdir[10][80];
  79.     char menufile[80], prompt[80], choice[40], execstr[80], user[80],
  80.           logfile[80], temp[80], temp2[80], iobuf[80];
  81.     char c;
  82.     int suspect = 0, access = NORMAL, vdirs = 2, count = 0,
  83.         chars, success, timeleft, i;
  84.  
  85. /* Set defaults, parse arguments */
  86.  
  87.     strcpy(menufile, "AXsh:etc/menu/main");
  88.     strcpy(prompt, "Choice (Q to quit): ");
  89.     strcpy(validdir[0], "AXsh:etc/menu");
  90.     strcpy(validdir[1], "Axsh:etc/adm");
  91.     if(argc != 1)
  92.     {
  93.         success = GetVar("accesslevel", temp, 80, GVF_LOCAL_ONLY);
  94.         if(!stricmp(temp, "superuser") || !stricmp(temp, "wizard") ||
  95.           !stricmp(temp, "assistant") || !stricmp(temp, "system"))
  96.           access = SUPERUSER;
  97.  
  98.         if(!stricmp(argv[1], "page"))
  99.         {
  100.             if(argc < 3) about();
  101.             success = GetVar("user", user, 80, GVF_LOCAL_ONLY);
  102.             strcpy(temp, "");
  103.             for(i = 2; i < argc; i++)
  104.             {
  105.                 strcat(temp, argv[i]);
  106.                 strcat(temp, " ");
  107.             }
  108.             sprintf(temp2, "Page %s %s", user, temp);
  109.             success = SetVar("MATRIX_MSG", temp2, 80, GVF_GLOBAL_ONLY);
  110.             std_error("Matrix: page sent");
  111.         }
  112.         if(!stricmp(argv[1], "force"))
  113.         {
  114.             if(argc < 3) about();
  115.             if(access != SUPERUSER)
  116.             {
  117.                 std_error("Matrix: access denied");
  118.             }
  119.             strcpy(temp, "");
  120.             for(i = 2; i < argc; i++)
  121.             {
  122.                 strcat(temp, argv[i]);
  123.                 strcat(temp, " ");
  124.             }
  125.             sprintf(temp2, "Frce %s", temp);
  126.             success = SetVar("MATRIX_MSG", temp2, 80, GVF_GLOBAL_ONLY);
  127.             std_error("Matrix: page sent");
  128.         }
  129.         if(!stricmp(argv[1], "chat"))
  130.         {
  131.             if(access != SUPERUSER) std_error("Matrix: access denied");
  132.             success = SetVar("MATRIX_MSG", "Chat", 80, GVF_GLOBAL_ONLY);
  133.             std_error("Matrix: chat request sent");
  134.         }
  135.         if(!stricmp(argv[1], "abort"))
  136.         {
  137.             if(access != SUPERUSER)    std_error("Matrix: access denied");
  138.             success = SetVar("MATRIX_MSG", "Abrt", 80, GVF_GLOBAL_ONLY);
  139.             std_error("Matrix: abort request sent");
  140.         }
  141.         if (argv[1][0] == '?' || argv[1][0] == '-') about();
  142.         strcpy(menufile, argv[1]);
  143.         if (argc > 2) strcpy(prompt, argv[2]);
  144.     }
  145.  
  146. /* Check menu file's validity */
  147.  
  148.     if(input = fopen("ENV:MATRIX_DIR", "r"))
  149.     {
  150.         while(!feof(input))
  151.         {
  152.             fscanf(input, "%s", validdir[vdirs]);
  153.             vdirs++;
  154.         }
  155.         fclose(input);
  156.     }
  157.     skip = TRUE;
  158.     for(i = 0; i < vdirs; i++)
  159.     {
  160.         if(!strnicmp(validdir[i], menufile, strlen(validdir[i])))
  161.             skip = FALSE;
  162.     }
  163.     if(skip == TRUE) std_error("Matrix: menu in illegal directory");
  164.         
  165. /* Get time, (re)open log */
  166.  
  167.     time_t t = time(NULL);            
  168.     struct tm *tp = localtime(&t);
  169.     strftime(logfile, sizeof(logfile) - 1, "AXsh:etc/adm/Log%d%m%y-Matrix", tp);
  170.     if(!(output = fopen(logfile, "a")))
  171.         std_error("Matrix: could not open logfile");
  172.     strftime(temp, sizeof(temp) - 1,
  173.         "Matrix log started on %A %d-%b-%y %H:%M:%S", tp);
  174.     success = GetVar("user", user, 80, GVF_LOCAL_ONLY);
  175.     fprintf(output, "%s by %s\n", temp, user);
  176.  
  177. /* Check for TimeOut, expert, and autologout */
  178.  
  179.     strcpy(temp, "Boing");
  180.     success = GetVar("timeout_active", temp, 80, GVF_GLOBAL_ONLY);
  181.     if(strcmp(temp, "Boing"))    /* Timeout exists */
  182.         timeout = TRUE;
  183.  
  184.     strcpy(temp, "Boing");
  185.     success = GetVar("expert", temp, 80, GVF_LOCAL_ONLY);
  186.     if(!strcmp(temp, "expert"))    /* Expert mode */
  187.         expert = TRUE;
  188.  
  189. /* Get the menu */
  190.  
  191.     showmenu(menufile, expert);
  192.     parsemenu(user);
  193.     fclose(input);
  194.  
  195. #ifdef DEBUG
  196.     for(i = 0; i < icount; i++)
  197.     {
  198.         printf("%d: %c %s %d %d %d\n", i, il[i].Key, il[i].Cmd, il[i].RawMode,
  199.             il[i].CheckPath, il[i].AskFile);
  200.     }
  201. #endif
  202.  
  203. /* Check & possibly launch the MatrixServer */
  204.  
  205. #ifdef VERSION_2
  206.     Forbid();
  207.     server_mp = (struct MsgPort *) FindPort("Matrix_Server");
  208.     Permit();
  209.     if(server_mp == 0)
  210.     {
  211.         /* Negotiations with Matrix_Server */
  212.     }
  213.     matrix_msg = (struct MatrixMsg *) AllocMem(sizeof(struct MatrixMsg),
  214.         MEMF_PUBLIC);
  215.     if(matrix_msg == 0)
  216.     {
  217.         freeallmem();
  218.         std_error("Matrix: not enough memory");
  219.     }
  220.  
  221.     (BPTR) matrix_mp = CreatePort("Matrix_Menu1", 0);
  222. #endif
  223.  
  224. /* Abort through special routine if CTRL-C'd */
  225.  
  226.     signal(SIGINT, breakexit);
  227.  
  228. /* Main loop */
  229.  
  230.     while(exit_chosen == FALSE)
  231.     {
  232.         strcpy(temp, "Boing");
  233.         success = GetVar("MATRIX_MSG", temp, 80, GVF_GLOBAL_ONLY);
  234.         if(strcmp(temp, "Boing"))    /* Message received */
  235.         {
  236.             DeleteVar("MATRIX_MSG", GVF_GLOBAL_ONLY);
  237.             if(!stricmp(temp, "Abrt"))
  238.             {
  239.                 puts("\n*** Superuser forced abort ***\n");
  240.                 fprintf(output, "*** Superuser forced abort, exiting ***\n");
  241.                 skip = TRUE;
  242.                 strcpy(choice, "MSG_ABRT");
  243.                 exit_chosen = TRUE;
  244.             }
  245.             if(!stricmp(temp, "Chat"))
  246.             {
  247.                 puts("\n*** Entering chat ***\n");
  248.                 fprintf(output, "*** Superuser forced chat ***\n");
  249.                 skip = TRUE;
  250.                 strcpy(choice, "MSG_CHAT");
  251.             }
  252.             if(!strnicmp(temp, "Frce", 4))
  253.             {
  254.                 sscanf(temp, "%s %[^\0]", temp2, execstr);
  255.                 puts("\n*** Superuser forced command ***\n");
  256.                 fprintf(output, "*** Superuser forced command ***\n%s\n", execstr);
  257.                 success = System(execstr, TAG_END);
  258.             }
  259.             if(!strnicmp(temp, "Page", 4))
  260.             {
  261.                 sscanf(temp, "%s %s %[^\0]", temp2, temp2, execstr);
  262.                 printf("\n*** Message from %s ***\n\n", temp2);
  263.                 printf("%s\n\n", execstr);
  264.             }
  265.         }    
  266.         if(timeout == TRUE)
  267.         {
  268.             lock = Lock("AXsh:etc/nologin", ACCESS_READ);
  269.             if(lock != 0)     /* File exists */
  270.             {
  271.                 UnLock(lock);
  272.                 input = fopen("AXsh:etc/nologin", "r");
  273.                 fgets(temp, 80, input);
  274.                 while(!feof(input))
  275.                 {
  276.                     printf("%s\n", temp);
  277.                     fgets(temp, 80, input);
  278.                 }
  279.                 fclose(input);
  280.                 fprintf(output, "*** Out of time, forced logout ***\n");
  281.                 skip = TRUE;
  282.                 exit_chosen = TRUE;
  283.                 strcpy(choice, "MSG_ABRT\n");
  284.             }
  285.             else
  286.             {
  287.                 success = GetVar("TIMELEFT", temp, 80, GVF_GLOBAL_ONLY);
  288.                 timeleft = atoi(temp);
  289.                 if(timeleft < 5)
  290.                     printf("*** Only %d min left ***\n", timeleft);
  291.                 else
  292.                     printf("(%d min left)\n", timeleft);
  293.             }
  294.         }
  295.  
  296. /* Check for strange input */
  297.  
  298.         if(suspect == 5)
  299.         {
  300.             puts("\nexit");
  301.             fprintf(output, "*** Suspected loss of carrier ***\n");
  302.             skip = TRUE;
  303.             strcpy(choice, "MSG_ABRT");
  304.             exit_chosen = TRUE;
  305.         }
  306.  
  307. /* Wait for input & messages */
  308.  
  309.         if(skip == FALSE)
  310.         {
  311.             printf("%s", prompt);
  312.             fflush(stdout);
  313.             fgets(choice, 35, stdin);
  314.             choice[strlen(choice) - 1] = 0;        /* Remove \n */
  315.             if(!strnicmp(choice, "MSG_", 4) && exit_chosen == FALSE)
  316.                 strcpy(choice, "?");
  317.             if(!strcmp(choice, "")) strcpy(choice, "?");
  318.         }
  319.         skip = FALSE;
  320.         cmddone = FALSE;
  321.         for(i = 0; i < icount; i++)
  322.         {
  323.             if(!stricmp(il[i].Key, choice))
  324.             {
  325.                 strcpy(execstr, il[i].Cmd);
  326.                 if(il[i].AskFile == TRUE)
  327.                 {
  328.                     printf("\n%s", il[i].String);
  329.                     fgets(temp, 80, stdin);
  330.                     if(il[i].CheckPath == TRUE)
  331.                     {
  332.                         success = strpbrk(temp, ":/$");
  333.                         if(success != 0)
  334.                         {
  335.                             puts("No paths or variables allowed!");
  336.                             skip = TRUE;
  337.                         }
  338.                     }
  339.                     strcat(execstr, " ");
  340.                     strcat(execstr, temp);
  341.                 }
  342.                 if(execstr[0] == '%')
  343.                 {
  344.                     cmddone = TRUE;
  345.                     if(!strnicmp(execstr, "%menu", 5))
  346.                     {
  347.                         strcpy(menufile, &execstr[6]);
  348.                         strcpy(prompt, il[i].String);
  349.                         showmenu(menufile, expert);
  350.                         parsemenu(user);
  351.                         fclose(input);
  352.                         cmddone = TRUE;
  353.                         newmenu = TRUE;
  354.                         fprintf(output, "menu: %s\n", menufile);
  355.                         break;
  356.                     }
  357.                     if(!strnicmp(execstr, "%xprt", 5))
  358.                     {
  359.                         if(expert == TRUE)
  360.                         {
  361.                             puts("Verbose mode selected.");
  362.                             success = SetVar("expert", "verbose", 80, GVF_LOCAL_ONLY);
  363.                             expert = FALSE;
  364.                         }
  365.                         else
  366.                         {
  367.                             puts("Expert mode selected.");
  368.                             success = SetVar("expert", "expert", 80, GVF_LOCAL_ONLY);
  369.                             expert = TRUE;
  370.                         }
  371.                         puts("To make your selection permanent, add one of these to your .login:\n");
  372.                         puts("set expert expert        (for expert mode)");
  373.                         puts("set expert verbose       (for verbose mode [default])\n");
  374.                         if(expert == FALSE)
  375.                         {
  376.                             puts("--- Press ENTER ---");
  377.                             fgets(temp, 80, stdin);
  378.                         }
  379.                         cmddone = TRUE;
  380.                         skip = TRUE;
  381.                     }
  382.                     if(!strnicmp(execstr, "%exit", 5) ||
  383.                         !strnicmp(execstr, "%quit", 5))
  384.                     {
  385.                         cmddone = TRUE;
  386.                         exit_chosen = TRUE;
  387.                         skip = TRUE;
  388.                     }
  389.                 }
  390.                 if(skip == FALSE)
  391.                 {
  392.                     if(il[i].RawMode == TRUE)
  393.                         setvbuf(stdin, NULL, _IONBF, 0);
  394.                     cmddone = TRUE;
  395.                     fprintf(output, "%s\n", il[i].Cmd);
  396.                     success = System(execstr, TAG_END);
  397.                     if(il[i].RawMode == TRUE)
  398.                         setvbuf(stdin, iobuf, _IOLBF, sizeof(iobuf));
  399.                     if(il[i].Pause == TRUE && expert == FALSE)
  400.                     {
  401.                         puts("--- Press ENTER ---");
  402.                         fgets(temp, 80, stdin);
  403.                     }
  404.                     if(!strnicmp(choice, "MSG_", 4)) break;
  405.                 }
  406.                 else
  407.                     skip = FALSE;
  408.             }
  409.         }
  410.         if(cmddone == FALSE || expert == FALSE)
  411.         {
  412.             if(exit_chosen == FALSE && newmenu == FALSE)
  413.             {
  414.                 showmenu(menufile, FALSE);    /* expert mode off */
  415.                 fclose(input);
  416.             }
  417.         }
  418.         newmenu = FALSE;
  419.         if (cmddone == FALSE) suspect++;
  420.     }
  421.     
  422.     matrix_msg->mm_Msg.mn_Node.ln_Type = NT_MESSAGE;
  423.     matrix_msg->mm_Msg.mn_Length = sizeof(struct MatrixMsg);
  424.     matrix_msg->mm_Msg.mn_ReplyPort = matrix_mp;
  425.     strcpy(matrix_msg->mm_Text, "Boing");
  426.     
  427. #ifdef VERSION_2
  428.     Forbid();
  429.     server_mp = FindPort("Matrix_Server");
  430.     if(server_mp)
  431.         PutMsg(server_mp, matrix_msg);
  432.     Permit();
  433. #endif
  434.  
  435.     time_t t = time(NULL);            
  436.     struct tm *tp = localtime(&t);
  437.     strftime(temp, sizeof(temp) - 1,
  438.         "Matrix log closed on %A %d-%b-%y %H:%M:%S", tp);
  439.     fprintf(output, "%s\n\n", temp);
  440.     fclose(output);
  441.  
  442. #ifdef VERSION_2
  443.     DeletePort((struct MsgPort *) matrix_mp);
  444.     freeallmem();
  445. #endif
  446.     exit(0);
  447. }
  448.  
  449. about()
  450. {
  451.     char *version = "\nMatrix for AXsh v"VERSION" by Guru Gnosis Sahib in 1994";
  452.  
  453.     puts(version);
  454.     puts("Usage: Matrix [menufile] [prompt]");
  455.     puts("       Matrix page [text]");
  456.     puts("       Matrix abort | chat | force <cmd> (superusers only)\n");
  457.     exit(0);
  458. }
  459.  
  460. showmenu(char menufile[80], BOOL expert)
  461. {
  462.     char temp[80];
  463.     int flag = FALSE;
  464.  
  465.     if(!(input = fopen(menufile, "r")))    std_error("Matrix: could not open menu file");
  466.     if(expert == FALSE) printf("\f"); else printf("\n");
  467.     fgets(temp, 80, input);
  468.     while(!feof(input) && flag == FALSE)
  469.     {
  470.         if(!strncmp(temp, "#", 1))
  471.         {
  472.             flag = TRUE;
  473.         }
  474.         else
  475.         {
  476.             if(expert == FALSE)
  477.                 printf("%s", temp);        /* puts() causes duplicate newlines */
  478.             fgets(temp, 80, input);
  479.         }
  480.     }
  481.     if (flag == FALSE)
  482.     {
  483.         fclose(input);
  484.         std_error("Matrix: not a Topic menu file");
  485.     }
  486. }
  487.  
  488. parsemenu(char user[80])
  489. {
  490.     char temp[80];
  491.     int offset = 3;
  492.  
  493.     icount = 1;
  494.     fgets(temp, 80, input);
  495.     while(!feof(input) || strncmp(temp, "#", 1))
  496.     {
  497.         offset = 3;
  498.         icount++;
  499.         strcpy(il[icount].Key, temp);
  500.         il[icount].Key[strlen(il[icount].Key) - 1] = '\0';  /* Remove \n */
  501.         fgets(il[icount].Cmd, 80, input);
  502.         il[icount].Cmd[strlen(il[icount].Cmd) - 1] = '\0';  /* Remove \n */
  503.  
  504.         fgets(temp, 80, input);
  505.         if(temp[3] == 'x')
  506.             offset = 6;            /* Extended optionset */
  507.  
  508. /* Standard Topic options */
  509.  
  510.         if(temp[0] == 'r')
  511.             il[icount].RawMode = TRUE;
  512.         else
  513.             il[icount].RawMode = FALSE;
  514.         if(temp[1] == 'p')
  515.             il[icount].CheckPath = TRUE;
  516.         else
  517.             il[icount].CheckPath = FALSE;
  518.         if(temp[2] == '?')
  519.         {
  520.             il[icount].AskFile = TRUE;
  521.             strcpy(il[icount].String, &temp[offset]);
  522.         }
  523.         else
  524.         {
  525.             il[icount].AskFile = FALSE;
  526.             if(offset == 3 || (temp[5] != 'm' && offset == 6))
  527.             {
  528.                 strcat(il[icount].Cmd, " ");
  529.                 strcat(il[icount].Cmd, &temp[offset]);
  530.                 il[icount].Cmd[strlen(il[icount].Cmd) - 1] = '\0';  /* Remove \n */
  531.                 strcpy(il[icount].String, "");
  532.             }
  533.         }
  534.  
  535. /* Extended Matrix options */
  536.  
  537.         il[icount].Pause = FALSE;
  538.         if(temp[3] == 'x')
  539.         {
  540.             if(temp[4] == 'z')
  541.             {
  542.                 il[icount].Pause = TRUE;
  543.             }
  544.             if(temp[5] == 'm')
  545.             {
  546.                 strcpy(il[icount].String, &temp[offset]);
  547.                 il[icount].String[strlen(il[icount].String) - 1] = '\0';
  548.             }
  549.         }
  550.         fgets(temp, 80, input);
  551.     }
  552.  
  553.     icount++;
  554.     strcpy(il[icount].Key, "MSG_CHAT");
  555.     strcpy(il[icount].Cmd, "AXsh:bin/chat");
  556.     il[icount].CheckPath = FALSE;
  557.     il[icount].RawMode = TRUE;
  558.     il[icount].AskFile = FALSE;
  559.     il[icount].Pause = FALSE;
  560.  
  561.     icount++;
  562.     strcpy(il[icount].Key, "MSG_ABRT");
  563.     strcpy(il[icount].Cmd, "%exit");
  564.     il[icount].CheckPath = FALSE;
  565.     il[icount].RawMode = FALSE;
  566.     il[icount].AskFile = FALSE;
  567.     il[icount].Pause = FALSE;
  568. }
  569.  
  570. freeallmem()
  571. {
  572.     if(matrix_msg) FreeMem(matrix_msg, sizeof(struct MatrixMsg));
  573. }
  574.  
  575. std_error(char text[80])
  576. {
  577.     puts(text);
  578.     exit(0);
  579. }
  580.  
  581. void breakexit()
  582. {
  583.     char temp[80];
  584.  
  585.     freeallmem();
  586.     puts("\n\n*** Matrix received BREAK, exiting ***\n");
  587.     fprintf(output, "*** Exit by BREAK ***\n");
  588.     time_t t = time(NULL);
  589.     struct tm *tp = localtime(&t);
  590.     strftime(temp, sizeof(temp) - 1,
  591.         "Matrix log closed on %A %d-%b-%y %H:%M:%S", tp);
  592.     fprintf(output, "%s\n\n", temp);
  593.     fclose(output);
  594.     exit(0);
  595. }
  596.